# 项目管理
from BlackWidow.tools import tools
from django import forms
from django.forms.models import model_to_dict
from BlackWidow.models import Project, User, ProjectPrototype
from django.http import JsonResponse
from BlackWidow.apis.user.manage import model_to_dict_with_url as user_model_to_dict_with_url
import os
from datetime import datetime
from django.db import models

def model_to_dict_with_time(model):
    """
    将模型对象转换为字典，并处理时间字段
    Args:
        model: 模型对象
    Returns:
        dict: 处理后的字典数据
    """
    model_dict = model_to_dict(model)
    # 将项目负责人转换为字典
    model_dict['project_leader'] = user_model_to_dict_with_url(model.project_leader)
    model_dict['create_time'] = model.create_time.strftime('%Y-%m-%d %H:%M:%S')
    model_dict['update_time'] = model.update_time.strftime('%Y-%m-%d %H:%M:%S')
    # 添加项目状态文本
    model_dict['project_status'] = {
        "name": model.get_project_status_display(),
        "id": model.project_status
    }
    # 获取项目原型图列表
    prototypes = ProjectPrototype.objects.filter(project=model)
    model_dict['prototypes'] = [{
        'prototype_id': proto.prototype_id,
        'prototype_name': proto.prototype_name,
        'prototype_description': proto.prototype_description,
        'prototype_url': proto.prototype_url.url if proto.prototype_url else None,
        'create_time': proto.create_time.strftime('%Y-%m-%d %H:%M:%S'),
        'update_time': proto.update_time.strftime('%Y-%m-%d %H:%M:%S')
    } for proto in prototypes] if prototypes else []
    return model_dict


class ProjectModelForm(forms.ModelForm):
    """
    项目表单类
    用于验证和处理项目数据的表单
    """
    class Meta:
        model = Project
        fields = [
            'project_name',
            'project_description', 
            'project_leader', 
            'project_doc_url', 
            'project_status'
            ]


    def clean_project_name(self):
        """
        项目名称验证
        确保项目名称符合要求
        """
        project_name = self.cleaned_data.get('project_name')
        if len(project_name) < 2:
            raise forms.ValidationError('项目名称不能少于2个字符')
        if len(project_name) > 50:
            raise forms.ValidationError('项目名称不能超过50个字符')
        return project_name

    def clean_project_status(self):
        """
        项目状态验证
        确保项目状态值有效
        """
        status = self.cleaned_data.get('project_status')
        valid_statuses = [choice[0] for choice in Project.project_status_choice]
        if status not in valid_statuses:
            raise forms.ValidationError('无效的项目状态')
        return status


def create_project(request):
    """
    创建项目
    处理项目创建请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        project_data = request.POST.copy()
        project_data['project_leader'] = request.user.user_id
        form = ProjectModelForm(project_data)
        if form.is_valid():
            try:
                # 创建项目
                form.save()
                project = form.instance
                
                # 返回项目信息
                project_data = model_to_dict_with_time(project)
                return JsonResponse(tools.ReturnData(0, '创建成功', data=project_data))
            except Exception as e:
                return JsonResponse(tools.ReturnData(1, f'创建失败: {str(e)}'))
        else:
            return JsonResponse(tools.ReturnData(1, '创建失败', tools.get_first_error(form)))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


def update_project(request):
    """
    更新项目
    处理项目更新请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        project_id = request.POST.get('project_id')
        if not project_id:
            return JsonResponse(tools.ReturnData(1, '项目ID不能为空'))

        try:
            project = Project.objects.get(project_id=project_id)
            # 验证是否是项目负责人
            if project.project_leader.user_id != request.user.user_id:
                return JsonResponse(tools.ReturnData(1, '无权限修改项目'))
        except Project.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '项目不存在'))

        project_data = request.POST.copy()
        project_data['project_leader'] = request.user.user_id
        form = ProjectModelForm(project_data, instance=project)
        if form.is_valid():
            try:
                # 更新项目
                project = form.save()
                
                # 返回更新后的项目信息
                project_data = model_to_dict_with_time(project)
                return JsonResponse(tools.ReturnData(0, '更新成功', data=project_data))
            except Exception as e:
                return JsonResponse(tools.ReturnData(1, f'更新失败: {str(e)}'))
        else:
            return JsonResponse(tools.ReturnData(1, '更新失败', tools.get_first_error(form)))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


def update_project_status(request):
    """
    更新项目状态
    处理项目状态更新请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        project_id = request.POST.get('project_id')
        project_status = request.POST.get('project_status')
        
        if not project_id:
            return JsonResponse(tools.ReturnData(1, '项目ID不能为空'))
        if not project_status:
            return JsonResponse(tools.ReturnData(1, '项目状态不能为空'))

        try:
            project = Project.objects.get(project_id=project_id)
            # 验证是否是项目负责人
            if project.project_leader.user_id != request.user.user_id:
                return JsonResponse(tools.ReturnData(1, '无权限修改项目状态'))
            
            # 验证状态值是否有效
            valid_statuses = [choice[0] for choice in Project.project_status_choice]
            if int(project_status) not in valid_statuses:
                return JsonResponse(tools.ReturnData(1, '无效的项目状态'))
            
            # 更新项目状态
            project.project_status = int(project_status)
            project.save()
            
            # 返回更新后的项目信息
            project_data = model_to_dict_with_time(project)
            return JsonResponse(tools.ReturnData(0, '状态更新成功', data=project_data))
        except Project.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '项目不存在'))
        except ValueError:
            return JsonResponse(tools.ReturnData(1, '项目状态必须是数字'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'更新失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


def delete_project(request):
    """
    删除项目
    处理项目删除请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        project_id = request.POST.get('project_id')
        if not project_id:
            return JsonResponse(tools.ReturnData(1, '项目ID不能为空'))

        try:
            project = Project.objects.get(project_id=project_id)
            # 验证是否是项目负责人
            if project.project_leader.user_id != request.user.user_id:
                return JsonResponse(tools.ReturnData(1, '无权限删除项目'))
            project.delete()
            return JsonResponse(tools.ReturnData(0, '删除成功'))
        except Project.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '项目不存在'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'删除失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


def get_project(request):
    """
    获取项目信息
    处理项目查询请求，支持多种查询条件
    Args:
        request: HTTP请求对象
        Query Parameters:
            project_id: 项目ID，指定时返回单个项目
            project_status: 项目状态，用于筛选
            search: 搜索关键词，匹配项目名称和描述
            leader_id: 项目负责人ID，用于筛选
            start_time: 开始时间，用于时间范围筛选
            end_time: 结束时间，用于时间范围筛选
            sort_by: 排序字段，支持 create_time, update_time, project_name
            sort_order: 排序方式，asc 或 desc
            page: 页码，默认1
            page_size: 每页数量，默认10，最大100
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'GET':
        try:
            # 获取查询参数
            project_id = request.GET.get('project_id')
            project_status = request.GET.get('project_status')
            search = request.GET.get('search')
            leader_id = request.GET.get('leader_id')
            start_time = request.GET.get('start_time')
            end_time = request.GET.get('end_time')
            sort_by = request.GET.get('sort_by', 'create_time')
            sort_order = request.GET.get('sort_order', 'desc')
            page = int(request.GET.get('page', 1))
            page_size = min(int(request.GET.get('page_size', 10)), 100)  # 限制最大页大小为100

            # 构建查询
            query = Project.objects.all()

            # 单个项目查询
            if project_id:
                project = query.get(project_id=project_id)
                project_data = model_to_dict_with_time(project)
                return JsonResponse(tools.ReturnData(0, '获取成功', data=project_data))

            # 应用筛选条件
            if project_status:
                try:
                    project_status = int(project_status)
                    valid_statuses = [choice[0] for choice in Project.project_status_choice]
                    if project_status not in valid_statuses:
                        return JsonResponse(tools.ReturnData(1, '无效的项目状态'))
                    query = query.filter(project_status=project_status)
                except ValueError:
                    return JsonResponse(tools.ReturnData(1, '项目状态必须是数字'))

            if search:
                query = query.filter(
                    models.Q(project_name__icontains=search) |
                    models.Q(project_description__icontains=search)
                )

            if leader_id:
                query = query.filter(project_leader_id=leader_id)

            if start_time:
                try:
                    start_time = datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S')
                    query = query.filter(create_time__gte=start_time)
                except ValueError:
                    return JsonResponse(tools.ReturnData(1, '开始时间格式错误'))

            if end_time:
                try:
                    end_time = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
                    query = query.filter(create_time__lte=end_time)
                except ValueError:
                    return JsonResponse(tools.ReturnData(1, '结束时间格式错误'))

            # 应用排序
            valid_sort_fields = ['create_time', 'update_time', 'project_name']
            if sort_by not in valid_sort_fields:
                sort_by = 'create_time'
            
            if sort_order.lower() == 'asc':
                query = query.order_by(sort_by)
            else:
                query = query.order_by(f'-{sort_by}')

            # 计算总数
            total_count = query.count()
            total_pages = (total_count + page_size - 1) // page_size

            # 应用分页
            start_index = (page - 1) * page_size
            end_index = start_index + page_size
            projects = query[start_index:end_index]

            # 转换数据
            projects_data = [model_to_dict_with_time(project) for project in projects]

            # 构建分页信息
            pagination = {
                'total': total_count,
                'page': page,
                'page_size': page_size,
                'total_pages': total_pages,
                'has_next': page < total_pages,
                'has_previous': page > 1
            }

            return JsonResponse(tools.ReturnData(0, '获取成功', data={
                'projects': projects_data,
                'pagination': pagination
            }))

        except Project.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '项目不存在'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'获取失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


def get_user_projects(request):
    """
    获取用户的项目列表
    处理用户项目查询请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'GET':
        project_status = request.GET.get('project_status')
        
        try:
            # 获取用户的项目列表
            projects = Project.objects.filter(project_leader_id=request.user.user_id)
            
            # 如果指定了状态，则按状态筛选
            if project_status:
                try:
                    project_status = int(project_status)
                    valid_statuses = [choice[0] for choice in Project.project_status_choice]
                    if project_status not in valid_statuses:
                        return JsonResponse(tools.ReturnData(1, '无效的项目状态'))
                    projects = projects.filter(project_status=project_status)
                except ValueError:
                    return JsonResponse(tools.ReturnData(1, '项目状态必须是数字'))
            
            # 按创建时间倒序排序
            projects = projects.order_by('-create_time')
            projects_data = [model_to_dict_with_time(project) for project in projects]
            return JsonResponse(tools.ReturnData(0, '获取成功', data=projects_data))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'获取失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


def add_project_prototype(request):
    """
    添加项目原型图
    处理项目原型图添加请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        project_id = request.POST.get('project_id')
        prototype_name = request.POST.get('prototype_name')
        prototype_description = request.POST.get('prototype_description')
        prototype_file = request.FILES.get('prototype_file')

        if not project_id:
            return JsonResponse(tools.ReturnData(1, '项目ID不能为空'))
        if not prototype_file:
            return JsonResponse(tools.ReturnData(1, '原型图文件不能为空'))

        try:
            # 验证项目是否存在且用户是否有权限
            project = Project.objects.get(project_id=project_id)
            if project.project_leader.user_id != request.user.user_id:
                return JsonResponse(tools.ReturnData(1, '无权限添加原型图'))

            # 创建原型图记录
            prototype = ProjectPrototype(
                project=project,
                prototype_name=prototype_name,
                prototype_description=prototype_description,
                prototype_url=prototype_file
            )
            prototype.save()

            # 返回更新后的项目信息
            project_data = model_to_dict_with_time(project)
            return JsonResponse(tools.ReturnData(0, '添加成功', data=project_data))
        except Project.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '项目不存在'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'添加失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


# 删除项目原型图
def delete_project_prototype(request):
    """
    删除项目原型图
    处理项目原型图删除请求
    """
    if request.method == 'POST':
        prototype_id = request.POST.get('prototype_id')
        if not prototype_id:
            return JsonResponse(tools.ReturnData(1, '原型图ID不能为空'))

        try:
            prototype = ProjectPrototype.objects.get(prototype_id=prototype_id)
            prototype.delete()
            # 本地文件的图片也要删除
            os.remove(prototype.prototype_url.path)
            return JsonResponse(tools.ReturnData(0, '删除成功'))
        except ProjectPrototype.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '原型图不存在'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'删除失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))

# 获取项目列表
